package ru.evga.billboard.editor;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JPanel;

import ru.evga.billboard.editor.behaviors.BehaviorManager;
import ru.evga.billboard.editor.behaviors.EditorContext;
import ru.evga.billboard.graph.Graph;
import ru.evga.billboard.graph.FrameSet.IFrameChangeListener;
import ru.evga.billboard.graph.preference.IPreferenceChangeListener;
import ru.evga.billboard.graph.preference.GraphSettings;


public class DrawPanel
    extends JPanel
    implements IPreferenceChangeListener, IFrameChangeListener

{
    
    private double zoom = 1;
    private Graph graph;
    private BehaviorManager behaviorManager;
    private EditorContext context; 
    private GraphSettings preference;

    public DrawPanel()
    {
        super(new BorderLayout());
        preference = new GraphSettings();
        preference.addChangeListener(this);
        graph = new Graph(preference);
        graph.getFrameSet().addListener(this);
        context =  new EditorContext(this);
        setFocusable(true);
        behaviorManager = new BehaviorManager(context);
        addMouseListener(behaviorManager);
        addMouseWheelListener(behaviorManager);
        addMouseMotionListener(behaviorManager);
        addKeyListener(behaviorManager);
    }

    public Dimension getPreferredSize()
    {
        Dimension parentSize = getParent().getSize();
        Rectangle2D bounds = graph.getClipBounds(context);
        int width = Math.max((int)(zoom * bounds.getMaxX()), (int)parentSize.getWidth());
        int height = Math.max((int)(zoom * bounds.getMaxY()), (int)parentSize.getHeight());
        return new Dimension(width, height);
    }

    public BehaviorManager getBehaviorManager()
    {
        return behaviorManager;
    }

    public double getZoom()
    {
        return zoom;
    }

    public void setZoom(double zoom)
    {
        this.zoom = zoom;
        revalidate();
        repaint();
    }

    public Graph getGraph()
    {
        return graph;
    }

    public GraphSettings getPreferens()
    {
        return preference;
    }
    
    @Override
    public void paint(Graphics g)
    {
        setBackground(preference.backgroundColor.getValue());
        super.paint(g);
        Graphics2D g2 = (Graphics2D)g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        //g2.scale(zoom, zoom);
        graph.paint(g2, context);
        behaviorManager.paint(g2);
    }
    
    @Override
    public void onPreferenceChanged(GraphSettings preference)
    {
        repaint();
    }
    
    @Override
    public void onChangeFrame(int frame)
    {
        repaint();
    }
    
    public void exportView(String fileName) throws Exception
    {
        Dimension s = getPreferredSize();
        BufferedImage bi = new BufferedImage(s.width, s.height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = bi.createGraphics();
        paint(g2);
        g2.dispose();
        try
        {
            String f = fileName.endsWith(".jpg") ? fileName : fileName + ".jpg";
            ImageIO.write(bi, "jpg", new File(f));
        }
        catch(IOException ioe)
        {
            System.out.println("Clip write help: " + ioe.getMessage());
        }

    }
}
